package cn.jbolt.core.service;

import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.common.enums.JBoltGlobalConfigTypeBuiltInEnum;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.common.enums.JBoltSystemLogType;
import cn.jbolt.core.enumutil.JBoltEnum;
import cn.jbolt.core.enumutil.JBoltEnumBean;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.GlobalConfigType;
import cn.jbolt.core.service.base.JBoltBaseService;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;

import java.util.List;

/**
 * 全局参数类型
 *
 * @ClassName: GlobalConfigTypeService
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年1月15日
 */
public class JBoltGlobalConfigTypeService extends JBoltBaseService<GlobalConfigType> {
	private final GlobalConfigType dao = new GlobalConfigType().dao();
	@Inject
	protected JBoltGlobalConfigService jboltGlobalConfigService;

	@Override
	protected GlobalConfigType dao() {
		return dao;
	}

	/**
	 * 后台管理使用数据
	 *
	 * @return
	 */
	public List<GlobalConfigType> getAdminList() {
		return getCommonList("sort_rank", "asc");
	}

	/**
	 * 保存
	 *
	 * @param type
	 * @return
	 */
	public Ret save(GlobalConfigType type) {
		return submit(type, false);
	}

	/**
	 * 修改更新
	 *
	 * @param type
	 * @return
	 */
	public Ret update(GlobalConfigType type) {
		return submit(type, true);
	}

	/**
	 * 提交
	 *
	 * @param type
	 * @param update
	 */
	private Ret submit(GlobalConfigType type, boolean update) {
		if (type == null || notOk(type.getName()) || notOk(type.getTypeKey()) || (!update && isOk(type.getId()))
				|| (update && notOk(type.getId()))) {
			return fail(JBoltMsg.PARAM_ERROR);
		}
		if(type.getBuiltIn() == null){
			type.setBuiltIn(false);
		}
		boolean success = false;
		// save和update分别处理
		if (update) {
			// 更新时需要判断数据存在
			GlobalConfigType dbType = findById(type.getId());
			if (dbType == null) {
				return fail(JBoltMsg.DATA_NOT_EXIST);
			}
			if (dbType.getBuiltIn()) {
				return fail("系统内置类型不可修改");
			}
			if (existsName(type.getName(), type.getId())) {
				return fail(JBoltMsg.DATA_SAME_NAME_EXIST);
			}
			if (exists("type_key", type.getTypeKey(), type.getId())) {
				return fail("KEY[" + type.getTypeKey() + "]已存在");
			}
			success = type.update();
			if (success && !dbType.getTypeKey().equals(type.getTypeKey())) {
				jboltGlobalConfigService.updateTypeKey(type.getId(), type.getTypeKey());
			}
		} else {
			if (existsName(type.getName(), -1)) {
				return fail(JBoltMsg.DATA_SAME_NAME_EXIST);
			}
			if (exists("type_key", type.getTypeKey(), -1)) {
				return fail("KEY[" + type.getTypeKey() + "]已存在");
			}
			if (type.getBuiltIn() != null && type.getBuiltIn()) {
				return fail("系统内置类型，内部自己维护");
			}
			type.setSortRank(getNextSortRank());
			type.setBuiltIn(false);
			success = type.save();
		}
		if (success) {
			// 添加日志
			addSystemLog(type.getId(), JBoltUserKit.getUserId(),(update ? JBoltSystemLogType.UPDATE.getValue(): JBoltSystemLogType.SAVE.getValue())
					, type.getName() + "[" + type.getTypeKey() + "]");
		}
		return ret(success);
	}

	/**
	 * 删除
	 *
	 * @param id
	 * @return
	 */
	public Ret delete(Long id) {
		return deleteById(id, true);
	}

	@Override
	protected String afterDelete(GlobalConfigType type, Kv kv) {
		// 更新sort_rank
		updateSortRankAfterDelete(type.getSortRank());
		// 添加日志
		addDeleteSystemLog(type.getId(), JBoltUserKit.getUserId(), JBoltSystemLogType.DELETE.getValue(),
				type.getName() + "[" + type.getTypeKey() + "]");
		return null;
	}

	@Override
	public String checkCanDelete(GlobalConfigType type, Kv kv) {
		return checkInUse(type, kv);
	}

	@Override
	public String checkInUse(GlobalConfigType type, Kv kv) {
		if (type.getBuiltIn()) {
			return "系统内置类型不可删除";
		}
		boolean inUseGlobalConfig = jboltGlobalConfigService.checkTypeInUse(type.getId(), type.getTypeKey());
		if (inUseGlobalConfig) {
			return "全局参数类型 " + type.getName() + "[" + type.getTypeKey() + "]下存在参数配置，不能直接删除";
		}
		return null;
	}

	/**
	 * 上移
	 *
	 * @param id
	 * @return
	 */
	public Ret doUp(Long id) {
		GlobalConfigType type = findById(id);
		if (type == null) {
			return fail("数据不存在或已被删除");
		}
		Integer rank = type.getSortRank();
		if (rank == null || rank <= 0) {
			return fail("顺序需要初始化");
		}
		if (rank == 1) {
			return fail("已经是第一个");
		}
		GlobalConfigType upType = findFirst(Okv.by("sort_rank", rank - 1));
		if (upType == null) {
			return fail("顺序需要初始化");
		}
		upType.setSortRank(rank);
		type.setSortRank(rank - 1);

		upType.update();
		type.update();
		return SUCCESS;
	}

	/**
	 * 下移
	 *
	 * @param id
	 * @return
	 */
	public Ret doDown(Long id) {
		GlobalConfigType type = findById(id);
		if (type == null) {
			return fail("数据不存在或已被删除");
		}
		Integer rank = type.getSortRank();
		if (rank == null || rank <= 0) {
			return fail("顺序需要初始化");
		}
		int max = getCount();
		if (rank == max) {
			return fail("已经是最后一个");
		}
		GlobalConfigType upType = findFirst(Okv.by("sort_rank", rank + 1));
		if (upType == null) {
			return fail("顺序需要初始化");
		}
		upType.setSortRank(rank);
		type.setSortRank(rank + 1);

		upType.update();
		type.update();
		return SUCCESS;
	}

	/**
	 * 初始化排序
	 */
	public Ret initRank() {
		List<GlobalConfigType> allList = findAll();
		if (allList.size() > 0) {
			for (int i = 0; i < allList.size(); i++) {
				allList.get(i).setSortRank(i + 1);
			}
			batchUpdate(allList);
			// 添加日志
			addUpdateSystemLog(null, JBoltUserKit.getUserId(),"所有数据","的顺序:初始化所有");
		}
		return SUCCESS;
	}

	/**
	 * 初始化
	 */
	public void checkAndInitTypes() {
		List<JBoltEnumBean> enums = JBoltEnum.getEnumOptionList(JBoltGlobalConfigTypeBuiltInEnum.class);
		for (JBoltEnumBean type : enums) {
			checkAndInitType(type);
		}
	}

	/**
	 * 检测并初始化type
	 *
	 * @param enumBean
	 */
	public void checkAndInitType(JBoltEnumBean enumBean) {
		GlobalConfigType type = findFirst(Okv.by("type_key", enumBean.getValue()));
		if (type == null) {
			type = new GlobalConfigType();
			type.setName(enumBean.getText());
			type.setTypeKey(enumBean.getValue().toString());
			type.setSortRank(getNextSortRank());
			type.setBuiltIn(true);
			boolean success = type.save();
			if (success) {
				jboltGlobalConfigService.updateTypeId(type.getTypeKey(), type.getId());
				// 添加日志
				addSaveSystemLog(type.getId(), JBoltUserKit.getUserId(),type.getName() + "[" + type.getTypeKey() + "]");
			}
		}
	}

	@Override
	protected int systemLogTargetType() {
		return JBoltSystemLogTargetType.GLOBAL_CONFIG_TYPE.getValue();
	}

}
